home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Sample Controls / PowerPlant View / CPPActiveX.cp next >
Encoding:
Text File  |  1996-12-14  |  13.6 KB  |  533 lines  |  [TEXT/CWIE]

  1. //    --------------------------------------------------------------------------------
  2. //    CPowerPlantAdaptor.cp
  3. //    (c) 1996 Microsoft Corporation.  All Rights Reserved.
  4. //
  5. //    This class is based on a smaller example from ocPPPict included in the ActiveX
  6. //    DR1 examples.  
  7. //
  8. //    The process here is very simple: events are routed through LGrafPortView in 
  9. //    PowerPlant.  There are some current "issues" that are being worked on:
  10. //
  11. //    o    This class should do more and you should derive from it.  Minimal effort 
  12. //        has gone into making this class very useful.
  13. //    o    I had to create a separate scroller class (CFixedScroller) because the
  14. //        regular PowerPlant one does Bad Things when included in an LGrafPort view.
  15. //        Read the notes in CFixedScroller for more on this.
  16. //
  17. //    o    You can't have more than one on a single page yet, unfortunately.
  18. //    --------------------------------------------------------------------------------
  19.  
  20. #include "ocheaders.h"
  21.  
  22. #include "CPPActiveX.h"
  23. #include "CCFragResource.h"
  24. #include "CTestView.h"
  25.  
  26. #include <UDrawingState.h>
  27. #include <UEnvironment.h>
  28. #include <URegistrar.h>
  29. #include <UReanimator.h>
  30. #include <LPeriodical.h>
  31.  
  32. static QDGlobalsPtr GetQDGlobals(void);
  33.  
  34. const ResIDT    DEFAULT_VIEW        = 1001;
  35. const Uint32    DefaultIdleRefCon    = 0;
  36.  
  37. extern void InitPowerPlantControl();
  38.  
  39. // --------------------------------------------------------------------------------
  40. // PowerPlant requires that if we're going to use LGrafPortView, we have
  41. // to setup some static variables first.  You can read all about this in
  42. // LGrafPortView.cp (double-click the word and hit command-D).
  43. // --------------------------------------------------------------------------------
  44.  
  45. void
  46. CPPActiveX::InitModule()
  47. {
  48.     UQDGlobals::SetQDGlobals( GetQDGlobals() );
  49.     Int32 qdVersion = gestaltOriginalQD;
  50.     Gestalt(gestaltQuickdrawVersion, &qdVersion);
  51.     UEnvironment::SetFeature(env_SupportsColor, (qdVersion > gestaltOriginalQD));    
  52.     
  53.     // Register our baseline objects.  This is bare miniumum stuff
  54.     
  55.     URegistrar::RegisterClass(LGrafPortView::class_ID,    (ClassCreatorFunc) LGrafPortView::CreateGrafPortViewStream);
  56.     URegistrar::RegisterClass(LPane::class_ID,            (ClassCreatorFunc) LPane::CreatePaneStream);
  57.     URegistrar::RegisterClass(LView::class_ID,            (ClassCreatorFunc) LView::CreateViewStream);
  58.     
  59.     InitPowerPlantControl();
  60. }
  61.  
  62. //    --------------------------------------------------------------------------------
  63. //    --------------------------------------------------------------------------------
  64.  
  65. CPPActiveX::CPPActiveX(void) 
  66.     :     CBaseControl(), 
  67.         LGrafPortView()
  68. {
  69.     InitModule();
  70.     
  71.     mMainView = nil;
  72.     mOwnedFoci = EmptyFocusSet;
  73. }
  74.  
  75.  
  76. //    --------------------------------------------------------------------------------
  77. //    Destructor.  Rather boring here.
  78. //    --------------------------------------------------------------------------------
  79.  
  80. CPPActiveX::~CPPActiveX()
  81. {
  82.     if (mMainView)
  83.         delete mMainView;
  84. }
  85.  
  86.  
  87. //    --------------------------------------------------------------------------------
  88. //    SetSite
  89. //    
  90. //    Tell our site we want idle time.
  91. //    --------------------------------------------------------------------------------
  92.  
  93. STDMETHODIMP
  94. CPPActiveX::SetSite(
  95.     IUnknown* inUnkSite)
  96. {
  97.     ErrorCode    theResult = E_FAIL;
  98.     
  99.     if (inUnkSite)
  100.     {
  101.         if (mContainerSiteP)
  102.         {
  103.             mContainerSiteP->SetIdleTime(RemoveAllIdlers, DefaultIdleRefCon);
  104.         }
  105.         
  106.         theResult = CBaseControl::SetSite(inUnkSite);
  107.         
  108.         if (theResult == S_OK && mContainerSiteP)
  109.         {
  110.             mContainerSiteP->SetIdleTime(::GetCaretTime(), DefaultIdleRefCon);
  111.         }
  112.     }
  113.     
  114.     return theResult;
  115. }
  116.  
  117.  
  118. //    --------------------------------------------------------------------------------
  119. //    Draw
  120. //    
  121. //    Very simple.  We have to adjust our size if need be (this was set to true in
  122. //    the constructor of this class).  We also place ourselves in the view and then
  123. //    tell the grafport to do its business.
  124. //    --------------------------------------------------------------------------------
  125.  
  126. STDMETHODIMP
  127. CPPActiveX::Draw(
  128.     DrawContext        *inContext)
  129. {
  130.     if (inContext->DrawAspect != DVASPECT_CONTENT)
  131.         return ResultFromScode(DV_E_DVASPECT);
  132.     
  133.     StColorPortState    savePortState(inContext->Port);
  134.     
  135.     CCFragResource    ResourceSetter;
  136.  
  137.     RealignSelf(inContext);
  138.     
  139.     FocusDraw();
  140.     LGrafPortView::Draw(nil);
  141.     OutOfFocus(nil);
  142.     
  143.     return S_OK;
  144. }
  145.  
  146. void
  147. CPPActiveX::DrawSelf()        // poor man's debug thing.  :-)
  148. {
  149.     if (mMainView == nil)
  150.     {
  151.         ::MoveTo(10, 10);
  152.         ::DrawString("\pPP View is empty.");
  153.     }
  154. }
  155.  
  156. //    --------------------------------------------------------------------------------
  157. //    NewContext
  158. //    
  159. //    create a new context info structure
  160. //    --------------------------------------------------------------------------------
  161.  
  162. CBaseContextInfo*
  163. CPPActiveX::NewContext(Uint32 inContextID)
  164. {
  165.     CPPContextInfo*    NewContextInfo = new CPPContextInfo(this, inContextID);
  166.  
  167.     if (!mMainView)
  168.     {
  169.         DrawContext        Context = {BeginPortType};
  170.         if (mContainerSiteP->AcquireContext(inContextID, &Context) == S_OK)
  171.         {
  172.             mMainView = CreateMainView();
  173.             if (mMainView) 
  174.                 mMainView->PutInside(this);
  175.  
  176.             mContainerSiteP->ReleaseContext(&Context);
  177.         }
  178.     }
  179.  
  180.     return NewContextInfo;
  181. }
  182.  
  183.  
  184. //    --------------------------------------------------------------------------------
  185. //    SetFocus
  186. //    
  187. //    Acquire or release a set of focus types.
  188. //    --------------------------------------------------------------------------------
  189.  
  190. STDMETHODIMP
  191. CPPActiveX::SetFocus(FocusCommand inCommand, FocusSet inFocus)
  192. {
  193.     ErrorCode            theResult = S_OK;
  194.     StColorPortState    savePort(UQDGlobals::GetCurrentPort());
  195.  
  196.     switch (inCommand)
  197.     {
  198.         case TakeNextCommand:
  199.         case TakePrevCommand:
  200.             if (mOwnedFoci)
  201.                 //    a TakeNext or a TakePrev on a control which doesn't embed and 
  202.                 //    has the focus should fail
  203.                 theResult = E_FAIL;
  204.             else
  205.             {
  206.                 //     if the container is offering us the one focus we want, take all of them
  207.                 if (inFocus & KeyboardFocus)
  208.                 {
  209.                     mOwnedFoci = FocusSet(mOwnedFoci | inFocus);
  210.                     LCommander* theSub = GetLatentSub();
  211.                     if (theSub)
  212.                         SwitchTarget(theSub);
  213.                 }
  214.                 else
  215.                 //    otherwise, say no thanks
  216.                     theResult = E_FAIL;
  217.             }
  218.             break;
  219.         case RequestReleaseCommand:
  220.         case ReleaseCommand:
  221.             mOwnedFoci = FocusSet(mOwnedFoci & ~inFocus);    //    really easy for us
  222.             if ((inFocus & KeyboardFocus) && IsOnDuty())
  223.             {
  224.                 SwitchTarget(nil);
  225.             }
  226.             break;
  227.     }
  228.     
  229.     return theResult;
  230. }
  231.  
  232.  
  233. //    --------------------------------------------------------------------------------
  234. //    DoMouse
  235. //    
  236. //    Handle a mouse event.
  237. //    --------------------------------------------------------------------------------
  238.  
  239. STDMETHODIMP
  240. CPPActiveX::DoMouse(
  241.     MouseEventType inMouseET, 
  242.     PlatformEvent* inEvent)
  243. {
  244.     CCFragResource        ResourceSetter;
  245.     DrawContext            Context = {BeginPortType};
  246.     
  247.     if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
  248.     {
  249.         RealignSelf(&Context);
  250.             
  251.         switch (inMouseET) 
  252.         {
  253.             case MouseDown:
  254.             case MouseUp:
  255.                 ClickInContent(*inEvent);
  256.                 break;
  257.         }
  258.  
  259.         mContainerSiteP->ReleaseContext(&Context);
  260.     }
  261.  
  262.     return S_OK;
  263. }
  264.  
  265. //    --------------------------------------------------------------------------------
  266. //    DoKey
  267. //    
  268. //    Handle a key event.
  269. //    --------------------------------------------------------------------------------
  270.  
  271. STDMETHODIMP
  272. CPPActiveX::DoKey(
  273.     KeyEventType    inKeyET, 
  274.     Char8            inChar, 
  275.     PlatformEvent*    inEvent)
  276. {
  277. #pragma unused (inChar)
  278.     CCFragResource        ResourceSetter;
  279.     DrawContext            Context = {BeginPortType};
  280.     
  281.     if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
  282.     {
  283.         RealignSelf(&Context);
  284.         
  285.         switch (inKeyET) 
  286.         {
  287.             case KeyDown:
  288.             case AutoKey:
  289.             {
  290.                 LCommander    *target = LCommander::GetTarget();
  291.                 if (target != nil)
  292.                     target->ProcessKeyPress(*inEvent);
  293.                 break;
  294.             }
  295.         }
  296.  
  297.         mContainerSiteP->ReleaseContext(&Context);
  298.     }
  299.  
  300.     return S_OK;
  301. }
  302.  
  303. //    --------------------------------------------------------------------------------
  304. //    DoIdle
  305. //    
  306. //    Perform idle time tasks.
  307. //    --------------------------------------------------------------------------------
  308.  
  309. STDMETHODIMP
  310. CPPActiveX::DoIdle(
  311.     Uint32            IdleRefCon)
  312. {
  313. #pragma unused (IdleRefCon)
  314.     CCFragResource        ResourceSetter;
  315.     DrawContext            Context = {BeginPortType};
  316.     EventRecord            theEvent;
  317.     
  318.     if (mContainerSiteP->AcquireContext(mActiveContext->GetContextID(), &Context) == S_OK)
  319.     {
  320.         theEvent.what = nullEvent;
  321.         theEvent.message = 0L;
  322.         theEvent.when = ::TickCount();
  323.         theEvent.where.h = theEvent.where.v = 0;
  324.         theEvent.modifiers = 0;
  325.         
  326.         RealignSelf(&Context);
  327.         
  328.         FocusDraw();
  329.         LPeriodical::DevoteTimeToIdlers(theEvent);
  330.         OutOfFocus(nil);
  331.  
  332.         mContainerSiteP->ReleaseContext(&Context);
  333.     }
  334.  
  335.     return S_OK;
  336. }
  337.  
  338. //    --------------------------------------------------------------------------------
  339. //    PutOnDuty
  340. //    
  341. //    This commander is going on duty (LCommander).
  342. //    --------------------------------------------------------------------------------
  343.  
  344. void
  345. CPPActiveX::PutOnDuty()
  346. {
  347.     if (!(mOwnedFoci & KeyboardFocus))
  348.     {
  349.         if (mContainerSiteP->RequestFocus(true, KeyboardFocus) == S_OK)
  350.             mOwnedFoci = FocusSet(mOwnedFoci | KeyboardFocus);
  351.     }
  352. }
  353.  
  354.  
  355. //    --------------------------------------------------------------------------------
  356. //    TakeOffDuty
  357. //    
  358. //    This commander is going off duty (LCommander).
  359. //    --------------------------------------------------------------------------------
  360.  
  361. void
  362. CPPActiveX::TakeOffDuty()
  363. {
  364.     if (mOwnedFoci & KeyboardFocus)
  365.     {
  366.         if (mContainerSiteP->RequestFocus(false, KeyboardFocus) == S_OK)
  367.             mOwnedFoci = FocusSet(mOwnedFoci & ~KeyboardFocus);
  368.     }
  369. }
  370.  
  371.  
  372. //    --------------------------------------------------------------------------------
  373. //    --------------------------------------------------------------------------------
  374.  
  375. void
  376. CPPActiveX::RealignSelf(
  377.     DrawContext     *inContext)
  378. {
  379.     RgnHandle    clip = inContext->Port->clipRgn;
  380.     
  381.     Rect    r = inContext->Location;
  382.     
  383.     ::OffsetRect(&r, -(inContext->Port->portRect.left), -(inContext->Port->portRect.top));
  384.  
  385.     PlaceInSuperFrameAt(r.left, r.top, false);
  386.     ResizeFrameTo( r.right - r.left, r.bottom -  r.top, false);
  387.     
  388.     if (clip != nil)
  389.     {
  390.         mRevealedRect = (**clip).rgnBBox;
  391.         ::OffsetRect(&mRevealedRect, -(inContext->Port->portRect.left), -(inContext->Port->portRect.top));
  392.     }
  393.     
  394.     if (mMainView != nil) mMainView->AdaptToNewSurroundings();
  395. }
  396.  
  397. //    --------------------------------------------------------------------------------
  398. //    --------------------------------------------------------------------------------
  399.  
  400. LView*
  401. CPPActiveX::CreateMainView()
  402. {
  403.     CCFragResource    resSaver;
  404.     
  405.     CTestView *theView = (CTestView*) UReanimator::ReadObjects('PPob', DEFAULT_VIEW);
  406.     if (theView)
  407.     {
  408.         theView->FinishCreate();
  409.     }
  410.     
  411.     return ((LView *) theView);
  412. }
  413.  
  414. //    --------------------------------------------------------------------------------
  415. //    --------------------------------------------------------------------------------
  416.  
  417. CPPContextInfo::CPPContextInfo(CPPActiveX* inControlP, Uint32 ContextID) : CBaseContextInfo(inControlP, ContextID)
  418. {
  419. }
  420.  
  421. //    --------------------------------------------------------------------------------
  422. //    --------------------------------------------------------------------------------
  423.  
  424. CPPContextInfo::~CPPContextInfo(void)
  425. {
  426. }
  427.  
  428. //    --------------------------------------------------------------------------------
  429. //    --------------------------------------------------------------------------------
  430.  
  431. ErrorCode
  432. CPPContextInfo::Activate(Boolean8 Acquired)
  433. {
  434. #pragma unused (Acquired)
  435.  
  436.     if (((CPPActiveX*)mControlP)->mMainView)
  437.         ((CPPActiveX*)mControlP)->Activate();
  438.  
  439.     return S_OK;
  440. }
  441.  
  442. //    --------------------------------------------------------------------------------
  443. //    --------------------------------------------------------------------------------
  444.  
  445. ErrorCode
  446. CPPContextInfo::Deactivate(Boolean8 Acquired)
  447. {
  448. #pragma unused (Acquired)
  449.  
  450.     if (((CPPActiveX*)mControlP)->mMainView)
  451.         ((CPPActiveX*)mControlP)->Deactivate();
  452.  
  453.     return S_OK;
  454. }
  455.  
  456.  
  457. //    --------------------------------------------------------------------------------
  458. //    --------------------------------------------------------------------------------
  459.  
  460. QDGlobalsPtr GetQDGlobals(void)
  461. {
  462.     ProcessSerialNumber PSN;
  463.     FSSpec                myFSSpec;
  464.     Str63                name;
  465.     ProcessInfoRec        infoRec;
  466.     OSErr                Result = noErr;
  467.     CFragConnectionID    connID;
  468.     Str255                 errName;
  469.     QDGlobalsPtr        QDGlobals = NULL;
  470.     //
  471.     // Ask the system if CFM is available.
  472.     //
  473.     long response;
  474.     OSErr err = ::Gestalt(gestaltCFMAttr, &response);
  475.     Boolean hasCFM = ::BitTst(&response, 31-gestaltCFMPresent);
  476.             
  477.     if (hasCFM)
  478.     {
  479.         //
  480.         // GetProcessInformation takes a process serial number and 
  481.         // will give us back the name and FSSpec of the application.
  482.         // See the Process Manager in IM.
  483.         //
  484.         infoRec.processInfoLength = sizeof(ProcessInfoRec);
  485.         infoRec.processName = name;
  486.         infoRec.processAppSpec = &myFSSpec;
  487.         
  488.         PSN.highLongOfPSN = 0;
  489.         PSN.lowLongOfPSN = kCurrentProcess;
  490.         
  491.         Result = ::GetProcessInformation(&PSN, &infoRec);
  492.     }
  493.     else
  494.         //
  495.         // If no CFM installed, assume it must be a 68K app.
  496.         //
  497.         Result = -1;        
  498.         
  499.     if (Result == noErr)
  500.     {
  501.         //
  502.         // Now that we know the app name and FSSpec, we can call GetDiskFragment
  503.         // to get a connID to use in a subsequent call to FindSymbol (it will also
  504.         // return the address of “main” in app, which we ignore).  If GetDiskFragment 
  505.         // returns an error, we assume the app must be 68K.
  506.         //
  507.         Ptr mainAddr;     
  508.         Result =  ::GetDiskFragment(infoRec.processAppSpec, 0L, 0L, infoRec.processName,
  509.                                   kLoadCFrag, &connID, (Ptr*)&mainAddr, errName);
  510.     }
  511.  
  512.     if (Result == noErr) 
  513.     {
  514.         //
  515.         // The app is a PPC code fragment, so call FindSymbol
  516.         // to get the exported “qd” symbol so we can access its
  517.         // QuickDraw globals.
  518.         //
  519.         CFragSymbolClass    SymClass;
  520.         Result = ::FindSymbol(connID, "\pqd", (Ptr*)&QDGlobals, &SymClass);
  521.     }
  522.     else
  523.         //
  524.         // The app is 68K, so use its A5 to compute the address
  525.         // of its QuickDraw globals.
  526.         //
  527.         QDGlobals = QDGlobalsPtr(*((long*)SetCurrentA5()) - (sizeof(QDGlobals) - sizeof(GrafPtr)));
  528.  
  529.     return QDGlobals;
  530. }
  531.  
  532.  
  533.